﻿using SpeakToMe.Core.Interfaces;
using SpeakToMe.Core.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpeakToMe.Data.User
{
    //A demo implementation of the IUserData interface that uses EF 5 for data access
    [Export(typeof(IUserData))]
    [PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.Shared)]
    public class UserData : IUserData
    {
        public Core.Models.User GetUserById(int id)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {
                var user = ctx.Users.Where(u => u.ID == id).FirstOrDefault();
                SpeakToMe.Core.Models.User theUser = new Core.Models.User
                {
                    FirstName = user.FirstName,
                    LastName = user.LastName,
                    ID = user.ID,
                    UserName = user.UserName,
                    ActiveConversations = new List<SpeakToMe.Core.Models.Conversation>()
                };

                ctx.Conversations.Where(c => c.User.ID == id).ToList().ForEach(a =>
                    {
                        var theConversation = new Core.Models.Conversation
                        {
                            Active = a.Active,
                            Address = a.Address,
                            ConversationHistory = new List<Core.Models.ConversationHistory>(),
                            ID = a.ID,
                            Initiated = a.Initiated,
                            Mode = a.Mode
                        };

                        theUser.ActiveConversations.Add(theConversation);

                        ctx.ConversationHistories.Where(h => h.Conversation.ID == a.ID).ToList().ForEach(c =>
                        {
                            theConversation.ConversationHistory.Add(new Core.Models.ConversationHistory
                            {
                                ID = c.ID,
                                Message = c.Message,
                                MessageDateTime = c.MessageDateTime,
                                Tag = c.Tag,
                                TagType = c.TagType,
                                UserInitiated = c.UserInitiated
                            });
                        });
                    });

                return theUser;
            }
        }


        public Core.Models.User CreateUser(string userName, string firstName, string lastName, string password)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {
                var user = new UserDataClass
                {
                    FirstName = firstName,
                    LastName = lastName,
                    UserName = userName
                };

                ctx.Users.Add(user);
                ctx.SaveChanges();

                return new Core.Models.User
                {
                    FirstName = user.FirstName,
                    ID = user.ID,
                    LastName = user.LastName,
                    UserName = user.UserName
                };
            }
        }

        public Conversation CreateConversation(int userId, Core.Enums.ConversationType type, string address)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {
                var conversation = new ConversationDataClass
                {
                    Active = true,
                    Address = address,
                    Initiated = DateTime.Now,
                    Mode = type
                };


                ctx.Conversations.Add(conversation);
                ctx.SaveChanges();

                return new Conversation
                {
                    Active = conversation.Active,
                    Address = conversation.Address,
                    ID = conversation.ID,
                    Initiated = conversation.Initiated,
                    Mode = conversation.Mode
                };
            }
        }

        public ConversationHistory AddConversationHistory(int conversationId, string text, string tagString, string tagType, bool userInitiated)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {

                var history = new ConversationHistoryDataClass
                {
                    Message = text,
                    MessageDateTime = DateTime.Now,
                    Tag = tagString,
                    TagType = tagType,
                    UserInitiated = userInitiated
                };

                ctx.ConversationHistories.Add(history);
                ctx.SaveChanges();

                return new ConversationHistory
                {
                    ID = history.ID,
                    Message = history.Message,
                    MessageDateTime = history.MessageDateTime,
                    Tag = history.Tag,
                    TagType = history.TagType,
                    UserInitiated = history.UserInitiated
                };
            }
        }


        public Conversation GetConversation(int userId, Core.Enums.ConversationType type, string address)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {

                var conversation = ctx.Conversations.Where(c => c.Mode == type && c.User.ID == userId && c.Address == address).FirstOrDefault();

                if (conversation == null)
                {
                    return CreateConversation(userId, type, address);
                }

                var foundConversation = new Conversation
                {
                    Active = true,
                    Address = address,
                    ID = conversation.ID,
                    Initiated = DateTime.Now,
                    Mode = type,
                    UserId = userId,
                    ConversationHistory = new List<ConversationHistory>()
                };

                foundConversation.ConversationHistory = new List<ConversationHistory>();

                conversation.ConversationHistory.ToList().ForEach(c =>
                    {
                        foundConversation.ConversationHistory.Add(new ConversationHistory
                        {
                            ID = c.ID,
                            Message = c.Message,
                            MessageDateTime = c.MessageDateTime,
                            Tag = c.Tag,
                            TagType = c.TagType,
                            UserInitiated = c.UserInitiated
                        });
                    });

                return foundConversation;
            }
        }

        public List<ConversationHistory> GetConversationHistory(int conversationId)
        {
            using (var ctx = new SpeakToMeContext("SpeakToMeContext"))
            {
                var history = ctx.ConversationHistories.Where(h => h.Conversation.ID == conversationId).ToList();

                List<ConversationHistory> newHistory = new List<ConversationHistory>();

                history.ForEach(h =>
                    {
                        newHistory.Add(new ConversationHistory
                        {
                            ID = h.ID,
                            Message = h.Message,
                            MessageDateTime = h.MessageDateTime,
                            Tag = h.Tag,
                            TagType = h.TagType,
                            UserInitiated = h.UserInitiated
                        });
                    });

                return newHistory;
            }
        }
    }
}
